﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Xaml;

namespace Prism.Core.Storage
{
    /// <summary>
    /// 存储管理器，提供差分版本存储功能。
    /// </summary>
    public abstract class StorageManager : IDataLoader
    {
        protected DifferentialDataTable DataTable { get; set; }

        protected Profile Profile { get; set; }

        protected StorageManager()
        {
            this.DataTable = new DifferentialDataTable();
            this.Profile = new Profile();
            this.Profile.DataTable = this.DataTable;
            this.Root = string.Empty;
        }

        protected StorageManager(string profileName)
            : this()
        {
            this.profilePath = Path.GetFullPath(profileName);
        }

        protected StorageManager(string profileName, string rootDir)
            : this()
        {
            this.profilePath = Path.Combine(rootDir, profileName);
            this.Root = rootDir;
        }

        protected string profilePath = Path.GetFullPath("dsc.xaml");

        /// <summary>
        /// 获取配置文件的路径。
        /// </summary>
        public string ProfilePath { get { return this.profilePath; } }

        /// <summary>
        /// 获取根目录。
        /// </summary>
        public string Root { get; protected set; }

        /// <summary>
        /// 启动管理器。
        /// </summary>
        public void ManagerOn()
        {
            // 在程序执行文件所属的目录下检测数据系统配置文件。

            // 如果不存在，则写入一个全新的。
            if (!File.Exists(profilePath))
            {
                var fs = new FileStream(profilePath, FileMode.CreateNew);
                XamlServices.Save(fs, this.Profile);
                fs.Close();
            }
            // 如果存在的话，读出数据。
            else
            {
                var fs = new FileStream(profilePath, FileMode.Open);
                this.Profile = XamlServices.Load(fs) as Profile;
                fs.Close();
                // 将读出的总表引用至本类下的总表属性。
                this.DataTable = this.Profile.DataTable;
            }

        }

        /// <summary>
        /// 重置管理器。
        /// </summary>
        public void Reset()
        {
            this.ManagerOn();
        }

        /// <summary>
        /// 更新配置文件到磁盘。
        /// </summary>
        public void UpdateProfileToDisk()
        {
            var fs = new FileStream(profilePath, FileMode.Create);
            XamlServices.Save(fs, this.Profile);
            fs.Close();
        }

        /// <summary>
        /// 获取最新版本的数据对应的流。
        /// </summary>
        /// <param name="accessName">识别数据用得名称。</param>
        /// <returns>返回取得的内存流。</returns>
        public Stream GetDataStream(string accessName)
        {
            return this.GetDataStream(accessName, this.DataTable.LastedVersion);
        }

        /// <summary>
        /// 指定数据版本获取数据对应的流。
        /// </summary>
        /// <param name="accessName">识别数据用得名称。</param>
        /// <param name="version">指定的版本。</param>
        /// <returns>返回取得的内存流。</returns>
        public Stream GetDataStream(string accessName, Version version)
        {
            var q = from dataList in this.DataTable
                    where dataList.Version.Value == version.Value
                    from data in dataList
                    where data.AccessName == accessName
                    select data;
            if (q.Count() == 1)
            {
                var target = q.Single();
                return target.GetData(this.Root);
            }
            else throw new DataNullException() { AccessName = accessName, Version = version };
        }
    }
}